// Copyright 2022 jeff.li. and/or its affiliates.

#include <gtest/gtest.h>
#include <tbir/runtime/generic/generic_unpack.h>
#include <iostream>

namespace tbir::runtime {

    TEST(Generic, kernel_builtins_len) {
        {
            Unicode a(U"abc");
            ASSERT_EQ(kernel_builtins_len(a), 3);
            Unicode b(U"\u6d4b\u8bd5\u96c6");
            ASSERT_EQ(kernel_builtins_len(b), 3);
        }
        {
            String a("abc");
            ASSERT_EQ(kernel_builtins_len(a), 3);
            String b("\u6d4b\u8bd5\u96c6");
            ASSERT_EQ(kernel_builtins_len(b), strlen("\u6d4b\u8bd5\u96c6"));
        }
        {
            List a({1, Unicode(U"HELLO"), String("HELLO")});
            List b({1, Unicode(U"WORLD"), String("WORLD")});
            ASSERT_EQ(kernel_builtins_len(a), 3);
            ASSERT_EQ(kernel_builtins_len(b), 3);
        }
        {
            Dict a({{1,               Unicode(U"HELLO")},
                    {String("HELLO"), String("World")}});
            ASSERT_EQ(kernel_builtins_len(a), 2);
        }
        {
            Set a({1, Unicode(U"HELLO"), String("HELLO")});
            Set b({1, Unicode(U"HELLO"), String("WORLD")});
            Set c({1, Unicode(U"HELLO"), Unicode(U"HELLO")});
            ASSERT_EQ(kernel_builtins_len(a), 3);
            ASSERT_EQ(kernel_builtins_len(b), 3);
            ASSERT_EQ(kernel_builtins_len(c), 2);
        }
        {
            auto d = std::make_pair(1, 2);
            EXPECT_EQ(kernel_builtins_len(d), 2);
        }
        {
            auto d = std::make_tuple(1, 2, 3);
            EXPECT_EQ(kernel_builtins_len(d), 3);
        }
    }

    TEST(Generic, kernel_builtins_unpack) {
        {
            Unicode a(U"abc");
            RTValue r = kernel_builtins_unpack<0, RTValue>(a);
            Unicode typed_r = r.As<Unicode>();
            ASSERT_EQ(typed_r, Unicode(U"a"));
            ASSERT_THROW((kernel_builtins_unpack<100, Unicode>(a)), Error);
        }
        {
            auto d = std::make_pair(1, 2);
            int64_t l1 = kernel_builtins_unpack<0, int64_t>(d);
            int64_t l2 = kernel_builtins_unpack<1, int64_t>(d);
            EXPECT_EQ(l1, 1);
            EXPECT_EQ(l2, 2);
        }
        {
            auto d = std::make_tuple(1, 2);
            int64_t l1 = kernel_builtins_unpack<0, int64_t>(d);
            int64_t l2 = kernel_builtins_unpack<1, int64_t>(d);
            EXPECT_EQ(l1, 1);
            EXPECT_EQ(l2, 2);
        }
    }

}  // namespace tbir::runtime
